package com.woniuxy.couponassembly.apiimpl;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.api.UserApi;
import com.woniuxy.api.UserCouponApi;
import com.woniuxy.common.Result;
import com.woniuxy.couponassembly.config.MQConfig;
import com.woniuxy.couponassembly.dao.CouponMapper;
import com.woniuxy.couponassembly.dao.UserCouponMapper;
import com.woniuxy.couponassembly.model.Coupon;
import com.woniuxy.couponassembly.model.ResultOrder;
import com.woniuxy.couponassembly.model.UserCoupon;
import com.woniuxy.couponassembly.service.ICouponService;
import com.woniuxy.couponassembly.service.IUserCouponService;
import com.woniuxy.form.UserCouponForm;
import com.woniuxy.form.UserVo;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RestController;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 用户优惠券关联表 前端控制器
 * </p>
 *
 * @author Liyfi
 * @since 2021-05-24
 */
@RestController
@Slf4j
@EnableAsync
public class UserCouponController  implements UserCouponApi
{

    ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private IUserCouponService service;

    @Autowired
    private ICouponService couponService;

    @Autowired
    private CouponMapper mapper;

    @Autowired
    private UserApi userApi;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private UserCouponMapper userCouponMapper;



    @Override
    public Result addUserCoupon(@RequestBody UserCouponForm userCouponForm) {
        log.info("用户新增优惠券,{}",userCouponForm);
        //查询优惠券库存
        Integer couponId = userCouponForm.getCouponId();
        int quantity = couponService.getIssuedQuantity(couponId);
        if(quantity == 0){
            return Result.fail("优惠券已换完");
        }else {
                //查询限购数量以及用户拥有数量
            int i = couponService.getCouponId(couponId);
            List<UserCoupon> coupons = service.findUserCouponByUserId(userCouponForm.getUserId(), userCouponForm.getCouponId());
            int size = coupons.size();
            if(size > i){
                return Result.fail("已经达到限购次数");
            }else {
                UserCoupon userCoupon = new UserCoupon();
                BeanUtils.copyProperties(userCouponForm,userCoupon);
                service.addCoupon(userCoupon);
                return Result.success("新增成功");
            }
        }
    }

    /**
     * 进入订单结算页面计算使用优惠券最优惠的价格
     * @param userId
     * @param price
     * @return
     */
    @Override
    public Result useCoupon(int userId,double price) {
        List<UserCoupon> userCoupons = service.findUserCouponBuUserId(userId);
        //满减金额
        double fullPrice = 0;
        //立减金额
        double immediatelyPrice = 0;
        //折扣金额
        double discountPrice = 0;
        int fullId = 0;
        int immediatelyId = 0;
        int discountId = 0;


        int couponId = 0;
        if(userCoupons.size() > 0){
            for (UserCoupon uc :userCoupons) {
                //如果获取的优惠券不为空则判断是否过期
                int i = couponService.findCoupon(uc.getCouponId());
                    if(i == 1){
                        continue;
                    }else {
                //如果没有过期则判断优惠券类型并做相应计算
                        Coupon coupon = mapper.findCoupon(uc.getCouponId());
                        String type = coupon.getCouponType();
                        if(type.equals("满减")){
                            Integer satisfy = coupon.getSatisfy();
                            if(satisfy > price){
                                continue;
                            } else {
                                Integer reduce = coupon.getReduce();
                                //将之前的价格存起来与现在的价格做比较,如果相同则不改变优惠券id,如果不相同则覆盖上一次id
                                double lastPrice = 0;
                                if(fullPrice != 0){
                                    lastPrice = fullPrice;
                                }
                                //判断之前的满减价格与现在的满减价格哪个更划算，并得到最终满减价格
                               fullPrice =  fullPrice == 0 ? price - reduce: fullPrice-(price - reduce) > 0 ? price - reduce : fullPrice ;
                               if(lastPrice != fullPrice){
                                   fullId = uc.getCouponId();
                               }
                                log.info("满减后价格为,{},id{}",fullPrice,fullId);
                            }
                        }else if(type.equals("立减")){
                            Integer reduce = coupon.getReduce();
                            //最终立减价格
                            double lastPrice = 0;
                            if(immediatelyPrice != 0){
                                lastPrice = immediatelyPrice;
                            }
                            immediatelyPrice  = immediatelyPrice == 0 ? price - reduce : immediatelyPrice - (price -reduce) >0 ? price - reduce : immediatelyPrice;
                            if(lastPrice != immediatelyPrice){
                                immediatelyId = uc.getCouponId();
                            }
                            log.info("立减后价格为,{},id{}",immediatelyPrice,immediatelyId);
                        }else {
                            //折扣

                            Double discount = coupon.getDiscount();
                            double lastPrice = 0;
                            if(discountPrice != 0){
                                lastPrice = discountPrice;
                            }
                            discountPrice = discountPrice == 0 ? price*discount:discountPrice - (price*discount) > 0 ? price*discount : discountPrice;
                            if(lastPrice != discountPrice){
                                discountId = uc.getCouponId();
                            }
                            log.info("折扣后价格为,{},id{}",discountPrice,discountId);
                        }
                    }
            }
            //计算最终价格
           double endPrice = fullPrice < immediatelyPrice ? fullPrice < discountPrice ? fullPrice : discountPrice : discountPrice < immediatelyPrice ? discountPrice : immediatelyPrice;
           //最终的优惠券Id
            couponId = endPrice == fullPrice ? fullId :endPrice == immediatelyPrice ? immediatelyId :discountId;
            log.info("最终价格为,id是,{},{}",endPrice,couponId);
            //将userId,couponId,price封装返回给前端
            ResultOrder resultOrder = new ResultOrder();
            resultOrder.setUserId(userId);
            resultOrder.setCouponId(couponId);
            resultOrder.setPrice(endPrice);
            return Result.success(resultOrder);
        }else {

            return Result.success(price);
        }
    }

    @Override
    public Result exchangeCoupons(UserCouponForm form) {

        Result result = userApi.findUser(form.getUserId());
        Object obj = result.getData();
        UserVo userVo = objectMapper.convertValue(obj,UserVo.class);
        log.info("用户,{}",userVo);
        Integer credit = userVo.getCredit();
        Integer couponId = form.getCouponId();
        Coupon coupon = couponService.selCoupon(couponId);
        Integer needCredit = coupon.getNeedCredit();
        if(credit > couponId){
            //如果积分足够就兑换
            UserCoupon userCoupon = new UserCoupon();
            BeanUtils.copyProperties(form,userCoupon);
            //新增用户优惠券
            service.addCoupon(userCoupon);
            //扣除用户积分
            userApi.cutBackCredit(needCredit,form.getUserId());
            return Result.success("兑换成功");
        }
        return Result.fail("兑换失败");
    }

    /**
     * 用户使用指定的优惠券
     * @param couponId
     * @param price
     * @return
     */
    @Override
    public Result userDesignatedCoupon( int couponId, double price,int userId) {
        Coupon coupon = mapper.findCoupon(couponId);
        String couponType = coupon.getCouponType();
        double endPrice  = 0;
        if("满减".equals(couponType)){
            Integer satisfy = coupon.getSatisfy();
            if(satisfy < price ){
               endPrice =  price - coupon.getReduce();
            }else {
                endPrice = price;
            }
            service.removeUserCoupon(userId,couponId);
        }else if("立减".equals(couponType)){
            endPrice = price - coupon.getReduce();
            service.removeUserCoupon(userId,couponId);
        }else {
            //折扣
            endPrice = price * coupon.getDiscount();
            service.removeUserCoupon(userId,couponId);
        }
        return Result.success(endPrice);
    }

    /**
     * 查询用户拥有的优惠券
     * @param userId
     * @return
     */
    @Override
    public Result findUserCoupon(int userId) {
        List<UserCoupon> coupons = service.findUserCouponBuUserId(userId);
        return Result.success(coupons);
    }


    /**
     * 新增秒杀token
     * @param couponId 优惠券Id
     * @param tokenQuantity 优惠券数量
     * @return
     */
    @Override
    public Result addSpikeToken(int couponId, int tokenQuantity) {
        Coupon coupon = mapper.findCoupon(couponId);
        log.info("coupon,{}",coupon);
        if(coupon == null){
            return Result.fail("该优惠券不存在");
        }
        //转成Long类型
//        String s = String.valueOf(couponId);
//        Long l = Long.parseLong(s);
        String a = String.valueOf(tokenQuantity);
        Long b = Long.parseLong(a);
        //生成令牌
        createCouponToken(couponId,b);
        return Result.success("正在生成令牌");
    }

    //异步多线程执行token
    @Async
    public void createCouponToken(int couponId,Long tokenQuantity){
        createListToken("coupon_",couponId,tokenQuantity);
    }

//    public List<String> getListToken(String keyPrefix, Long tokenQuantity,int redisKey) {
////        List<String> listToken = new ArrayList<>();
//        for (int i = 0; i < tokenQuantity; i++) {
//            String token = keyPrefix + UUID.randomUUID().toString().replace("-", "");
//            redisTemplate.opsForList().leftPush(redisKey,token);
////            listToken.add(token);
//        }
////        return listToken;
//    }


    public void createListToken(String keyPrefix, int redisKey, Long tokenQuantity) {
//        List<String> listToken = getListToken(keyPrefix, tokenQuantity);
        for (int i = 0; i < tokenQuantity; i++) {
            String token = keyPrefix + UUID.randomUUID().toString().replace("-", "");
            redisTemplate.opsForList().leftPush(redisKey,token);
//            listToken.add(token);
        }
    }




    /**
     * 秒杀
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result spike(int userId, int couponId) {
        log.info("###>>>>>秒杀接口线程池名称:" + Thread.currentThread().getName());
        String s = String.valueOf(couponId);
        Long l = Long.parseLong(s);
        if(l == null){
            return Result.fail("优惠券Id不能为空！");
        }
        //从redis处获取秒杀token
        String value = getListKeyToken(couponId);
        log.info("value,{}",value);


        if(StringUtils.isEmpty(value)){
            log.info("已经卖完咯,{},{}",couponId,value);
            return  Result.fail("已经卖完了");
        }
        List<UserCoupon> userCouponByCoupon = userCouponMapper.findUserCouponByCoupon(userId);
        if(userCouponByCoupon.size()>0){
            return Result.fail("系统异常");
        }
        //异步放入mq中实现修改商品的库存
        sendCouponMsg(couponId,userId);

        return Result.success("正在排队。。。");
    }

    
    //获取value
        public String getListKeyToken(int key) {
        String value = (String) redisTemplate.opsForList().leftPop(key);

        log.info("移除的元素是,{}",value);
        return value;
    }


    @Async
    public void sendCouponMsg(int couponId, int userId) {
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("couponId", couponId);
            jsonObject.put("userId", userId);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        send(jsonObject);
    }

    @Transactional(rollbackFor = Exception.class)
    public void send(JSONObject jsonObject) {

        String jsonString = jsonObject.toString();
        System.out.println("jsonString:" + jsonString);
//        String messAgeId = UUID.randomUUID().toString().replace("-", "");
        // 封装消息
        rabbitTemplate.convertAndSend(MQConfig.USER_EXCHANGE, MQConfig.USER_BINDING,jsonString);
    }
}

